Fix default templates crashing when card model is transiently undefined - #5608
Closed
christse wants to merge 1 commit into
Closed
Fix default templates crashing when card model is transiently undefined#5608christse wants to merge 1 commit into
christse wants to merge 1 commit into
Conversation
The default isolated/edit template derived the card class from model.constructor inside tracked getters. The host can render a format component for a tick while the model instance is still resolving (initial load, or a store re-resolve after an incremental index invalidation lands under an open card), which crashed the render with "Cannot read properties of undefined (reading 'constructor')". The class is already passed to every format component as @cardOrField — head.gts and embedded.gts use it for exactly this reason — so take it from there instead of digging it out of the instance. Same rework in field-edit.gts, which had the identical pattern. Guard the remaining @fields dereferences and render the CardInfo edit header and notes footer only when @fields is populated, so a render pass with no data produces an empty shell instead of throwing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
|
[Claude Code 🤖] Closing: this fix was made while working on a userland realm project, and platform changes shouldn't ride along with that work. The affected realm is shielded by a realm-side guarded default template, so nothing depends on this landing. CS-12330 remains the tracking ticket for the underlying host issue (default templates crash when the card model is transiently undefined); the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Production host intermittently crashes while rendering a card:
The default isolated/edit template derives the card class from
this.args.model.constructorinside tracked getters, and dereferencesthis.args.fieldsunguarded. The host can render a format component for a tick while the model instance is still resolving — on initial load, and on a store re-resolve when an incremental index invalidation lands under an open card — so the first tracked getter throws and takes down the render. Reproduced repeatedly on a realm with heavylinksTographs and frequent CLI pushes (live invalidations of open cards).Fix
@cardOrFieldinstead ofmodel.constructor. Every format component already receives the class as an arg, independent of the instance —head.gtsandembedded.gtsuse it for exactly this reason.isolated-and-edit.gtsandfield-edit.gtswere the two templates digging it out of the instance instead.@fieldsdereferences (displayFields,isThemeCard) and render the CardInfo edit header and notes footer only when@fields.cardInfoexists — invoking<@fields.cardInfo.notes />with undefined@fieldsthrows "attempted to invoke undefined component".Behavior is unchanged whenever model/fields are present; a render pass with no data now produces an empty shell for that frame instead of throwing. This matches the defensive convention
card-info.gtsalready follows throughout.Verification
ember-template-lintclean on both fileslint:typeserror count identical before/after (7 pre-existing, unrelated.at()lib-target errors)packages/basegts files (the eslint config doesn't parse<template>there; the package's own lint is ember-template-lint, which passes)card-basics-test) are unaffected by construction — the guards only change behavior when fields are absent, which previously crashedTracked in CS-12330.
🤖 Generated with Claude Code